package com.free4inno.knowledgems.service;

import com.free4inno.knowledgems.dao.GroupInfoDAO;
import com.free4inno.knowledgems.dao.LabelInfoDAO;
import com.free4inno.knowledgems.dao.UserDAO;
import com.free4inno.knowledgems.domain.GroupInfo;
import com.free4inno.knowledgems.domain.LabelInfo;
import com.free4inno.knowledgems.domain.ResourceES;
import com.free4inno.knowledgems.domain.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.HashSet;
import java.util.List;

@Slf4j
@Service
public class SearchService {

    @Autowired
    private UserDAO userDAO;

    @Autowired
    private LabelInfoDAO labelInfoDAO;

    @Autowired
    private GroupInfoDAO groupInfoDAO;

    public List<ResourceES> buildResourceES(List<ResourceES> resourceESList) {
        // 1. build 3 hash set to De-duplication : author, label, group
        HashSet<Integer> usersId = new HashSet<>();
        HashSet<Integer> labelsId = new HashSet<>();
        HashSet<Integer> groupsId = new HashSet<>();
        for (ResourceES resourceES : resourceESList) {
            // 1.1. author
            if (resourceES.getUser_id() != null) {
                int userId = resourceES.getUser_id();
                usersId.add(userId);
            }
            // 1.2. label
            if (resourceES.getLabel_id() != null && !resourceES.getLabel_id().equals("")) {
                //System.out.println(resourceES.getTitle());
                //System.out.println(resourceES.getLabel_id());
                String[] label = resourceES.getLabel_id().split(",|，");
                for (String s : label) {
                    if(s == "" || s.isEmpty()) continue;
                    int labelId = (s == "" ? 0 : Integer.parseInt(s));
                    labelsId.add(labelId);
                }
            }
            // 1.3. group
            if (resourceES.getGroup_id() != null && !resourceES.getGroup_id().equals("")) {
                String[] group = resourceES.getGroup_id().split(",|，");
                for (String s : group) {
                    if(s == "" || s.isEmpty()) continue;
                    int groupId = (s == "" ? 0 : Integer.parseInt(s));
                    groupsId.add(groupId);
                }
            }
        }

        // 2. build 3 hash map to save all string names
        HashMap<Integer, String> usersName = new HashMap<>();
        HashMap<Integer, String> labelsName = new HashMap<>();
        HashMap<Integer, String> groupsName = new HashMap<>();
        // 2.1. author
        for (Integer userId : usersId) {
            User user = userDAO.findById(userId).orElse(new User());
            if (user.getRealName() != null) {
                usersName.put(userId, user.getRealName());
            } else {
                usersName.put(userId, "自邮之翼" + userId);
            }
        }
        // 2.2. label
        for (Integer labelId : labelsId) {
            LabelInfo labelInfo = labelInfoDAO.findById(labelId).orElse(new LabelInfo());
            if (labelInfo.getLabelName() != null) {
                String ln = labelInfo.getLabelName();
                labelsName.put(labelId, ln);
            } else {
                labelsName.put(labelId, "未知标签" + labelId);
            }
        }
        // 2.3. group
        for (Integer groupId : groupsId) {
            GroupInfo groupInfo = groupInfoDAO.findById(groupId).orElse(new GroupInfo());
            if (groupInfo.getGroupName() != null) {
                String gn = groupInfo.getGroupName();
                groupsName.put(groupId, gn);
            } else {
                groupsName.put(groupId, "未知群组" + groupId);
            }
        }

        // 3. Loop Process
        for (ResourceES resourceES : resourceESList) {
            // 3.1. use names in map, reduce interactions with DB

            // 取作者名
            if (resourceES.getUser_id() != null) {
                int userId = resourceES.getUser_id();
                resourceES.setUser_name(usersName.get(userId));
            }
            // 取群组名
            String groupName = "";
            if (resourceES.getGroup_id() != null && !resourceES.getGroup_id().equals("")) {
                String[] group = resourceES.getGroup_id().split(",|，");
                for (String s : group) {
                    if(s == "" || s.isEmpty()) continue;
                    int groupId = (s == "" ? 0 : Integer.parseInt(s));
                    groupName = groupName + "," + groupsName.get(groupId);
                }
                groupName = groupName.substring(1);
            } else {
                groupName = "该资源无群组";
            }
            resourceES.setGroup_name(groupName);
            // 取标签名
            String labelName = "";
            if (resourceES.getLabel_id() != null && !resourceES.getLabel_id().equals("")) {
                String[] label = resourceES.getLabel_id().split(",|，");
                for (String s : label) {
                    if(s == "" || s.isEmpty()) continue;
                    int labelId = (s == "" ? 0 : Integer.parseInt(s));
                    labelName = labelName + "," + labelsName.get(labelId);
                }
                labelName = labelName.substring(1);
            } else {
                labelName = "该资源无标签";
            }
            resourceES.setLabel_name(labelName);

            // 3.2. get hit point
            String text = resourceES.getText().replaceAll("<.*?>", "");
            String title = resourceES.getTitle();
            resourceES.setText(text.length() > 100 ? text.substring(0, 100) + "... ..." : text);
            resourceES.setTitle(title.replaceAll("<.*?>", ""));

            // 3.2. get hit point
            if (resourceES.getInnerHitsContent() != null) {
                //标记搜索命中来源
                if (resourceES.getInnerHitsContent().get("attachment").getHits().length == 0) {
                    resourceES.setAttach_search_flag(0);
                } else {
                    resourceES.setAttach_search_flag(1);
                }
                if (resourceES.getInnerHitsContent().get("comment").getHits().length == 0) {
                    resourceES.setComment_search_flag(0);
                } else {
                    resourceES.setComment_search_flag(1);
                }
            } else {
                resourceES.setAttach_search_flag(0);
                resourceES.setComment_search_flag(0);
            }
            // delete `innerHitsContent`
            resourceES.setInnerHitsContent(null);
            // delete `attachment`
            resourceES.setAttachment(null);
            // delete `highlight`
            resourceES.setHighlight(null);
            // delete `comment`
            resourceES.setComment(null);
        }

        return resourceESList;
    }
}
